----------------------------------------------------------------------------------
-- CPEG 422 spartan-3e base
-- Jason Parrott
-- Rodney McGee
-- Ray Delvecchio
-- Juergen Ributzka
-- Jack Welsh
-- Ryan Hoover
-- Mike Stamat
-- Lee Reed
--
-- Keyboard wrapper
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

entity keyboard_top is
  port (
    PS2_data   : inout std_logic;
    PS2_clk    : inout std_logic;
    LED        : out   std_logic_vector(7 downto 0);
    clk        : in    std_logic;
    reset      : in    std_logic;
    data_ready : out   std_logic;
    ascii_out  : out   std_logic_vector (7 downto 0));
end keyboard_top;

architecture Behavioral of keyboard_top is

  component keyboard
    port (
      ps2_clk                  : inout std_logic;
      ps2_data                 : inout std_logic;
      clk                      : in    std_logic;
      reset                    : in    std_logic;
      rx_extended              : out   std_logic;
      rx_released              : out   std_logic;
      rx_shift_key_on          : out   std_logic;
      rx_scan_code             : out   std_logic_vector(7 downto 0);
      rx_ascii                 : out   std_logic_vector(7 downto 0);
      rx_data_ready            : out   std_logic;
      rx_read                  : in    std_logic;
      tx_data                  : in    std_logic_vector(7 downto 0);
      tx_write                 : in    std_logic;
      tx_write_ack_o           : out   std_logic;
      tx_error_no_keyboard_ack : out   std_logic
      );
  end component;

  signal ascii_buffer : std_logic_vector (7 downto 0);
  signal scan_code    : std_logic_vector (7 downto 0);
  signal scan_ready   : std_logic;
  signal shift_key    : std_logic;
  signal released     : std_logic;
  signal read         : std_logic;

begin

  K1 : keyboard
    port map(
      clk             => clk,
      reset           => reset,
      rx_read         => read,
      ps2_clk         => ps2_clk,
      ps2_data        => ps2_data,
      rx_data_ready   => scan_ready,
      rx_scan_code    => scan_code,
      rx_shift_key_on => shift_key,
      --rx_ascii => led,
      rx_released     => released,
      tx_data         => "00000000",
      tx_write        => '0'
      );

  ascii_buffer <= x"30" when scan_code = x"45" and shift_key = '0' else  --0
                  x"31" when scan_code = x"16" and shift_key = '0' else  --1
                  x"32" when scan_code = x"1E" and shift_key = '0' else  --2
                  x"33" when scan_code = x"26" and shift_key = '0' else  --3
                  x"34" when scan_code = x"25" and shift_key = '0' else  --4
                  x"35" when scan_code = x"2E" and shift_key = '0' else  --5
                  x"36" when scan_code = x"36" and shift_key = '0' else  --6
                  x"37" when scan_code = x"3D" and shift_key = '0' else  --7
                  x"38" when scan_code = x"3E" and shift_key = '0' else  --8
                  x"39" when scan_code = x"46" and shift_key = '0' else  --9
                  x"41" when scan_code = x"1C" and shift_key = '1' else  --A
                  x"42" when scan_code = x"32" and shift_key = '1' else  --B
                  x"43" when scan_code = x"21" and shift_key = '1' else  --C
                  x"44" when scan_code = x"23" and shift_key = '1' else  --D
                  x"45" when scan_code = x"24" and shift_key = '1' else  --E
                  x"46" when scan_code = x"2B" and shift_key = '1' else  --F
                  x"47" when scan_code = x"34" and shift_key = '1' else  --G
                  x"48" when scan_code = x"33" and shift_key = '1' else  --H
                  x"49" when scan_code = x"43" and shift_key = '1' else  --I
                  x"4A" when scan_code = x"3B" and shift_key = '1' else  --J
                  x"4B" when scan_code = x"42" and shift_key = '1' else  --K
                  x"4C" when scan_code = x"4B" and shift_key = '1' else  --L
                  x"4D" when scan_code = x"3A" and shift_key = '1' else  --M
                  x"4E" when scan_code = x"31" and shift_key = '1' else  --N
                  x"4F" when scan_code = x"44" and shift_key = '1' else  --O
                  x"50" when scan_code = x"4D" and shift_key = '1' else  --P
                  x"51" when scan_code = x"15" and shift_key = '1' else  --Q
                  x"52" when scan_code = x"2D" and shift_key = '1' else  --R
                  x"53" when scan_code = x"1B" and shift_key = '1' else  --S
                  x"54" when scan_code = x"2C" and shift_key = '1' else  --T
                  x"55" when scan_code = x"3C" and shift_key = '1' else  --U
                  x"56" when scan_code = x"2A" and shift_key = '1' else  --V
                  x"57" when scan_code = x"1D" and shift_key = '1' else  --W
                  x"58" when scan_code = x"22" and shift_key = '1' else  --X
                  x"59" when scan_code = x"35" and shift_key = '1' else  --Y
                  x"5A" when scan_code = x"1A" and shift_key = '1' else  --Z
                  x"61" when scan_code = x"1C" and shift_key = '0' else  --a
                  x"62" when scan_code = x"32" and shift_key = '0' else  --b
                  x"63" when scan_code = x"21" and shift_key = '0' else  --c
                  x"64" when scan_code = x"23" and shift_key = '0' else  --d
                  x"65" when scan_code = x"24" and shift_key = '0' else  --e
                  x"66" when scan_code = x"2B" and shift_key = '0' else  --f
                  x"67" when scan_code = x"34" and shift_key = '0' else  --g
                  x"68" when scan_code = x"33" and shift_key = '0' else  --h
                  x"69" when scan_code = x"43" and shift_key = '0' else  --i
                  x"6A" when scan_code = x"3B" and shift_key = '0' else  --j
                  x"6B" when scan_code = x"42" and shift_key = '0' else  --k
                  x"6C" when scan_code = x"4B" and shift_key = '0' else  --l
                  x"6D" when scan_code = x"3A" and shift_key = '0' else  --m
                  x"6E" when scan_code = x"31" and shift_key = '0' else  --n
                  x"6F" when scan_code = x"44" and shift_key = '0' else  --o
                  x"70" when scan_code = x"4D" and shift_key = '0' else  --p
                  x"71" when scan_code = x"15" and shift_key = '0' else  --q
                  x"72" when scan_code = x"2D" and shift_key = '0' else  --r
                  x"73" when scan_code = x"1B" and shift_key = '0' else  --s
                  x"74" when scan_code = x"2C" and shift_key = '0' else  --t
                  x"75" when scan_code = x"3C" and shift_key = '0' else  --u
                  x"76" when scan_code = x"2A" and shift_key = '0' else  --v
                  x"77" when scan_code = x"1D" and shift_key = '0' else  --w
                  x"78" when scan_code = x"22" and shift_key = '0' else  --x
                  x"79" when scan_code = x"35" and shift_key = '0' else  --y
                  x"7A" when scan_code = x"1A" and shift_key = '0' else  --z
                  x"2d" when scan_code = x"4e" and shift_key = '0' else  ---
                  x"5f" when scan_code = x"4e" and shift_key = '1' else  --_
                  x"08" when scan_code = x"66" and shift_key = '0' else  --BS
                  x"0d" when scan_code = x"5a" and shift_key = '0' else  --Enter
                  x"00";

  process(clk, reset) is
                      variable ignoreNextCode : std_logic := '0';
  begin
    if (reset = '1') then
      data_ready       <= '0';
      ignoreNextCode                                      := '0';
      read             <= '1';
    elsif (rising_edge(clk)) then
      if(scan_ready = '1' and released = '0') then
        read           <= '1';
        if(scan_code = x"F0") then
          data_ready   <= '0';
          ignoreNextCode                                  := '1';
        else
          if(ignoreNextCode = '1') then
            data_ready <= '0';
            ignoreNextCode                                := '0';
          else
            data_ready <= '1';
            ascii_out  <= ascii_buffer;
          end if;
        end if;
      else
        read           <= '0';
        data_ready     <= '0';
      end if;
    end if;
  end process;

  --led <= scan_code;

end Behavioral;

